package gbench.sandbox.record;

import org.junit.jupiter.api.Test;

import java.time.LocalDateTime;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import gbench.common.tree.LittleTree.IRecord;
import gbench.common.tree.LittleTree.SQL;
import gbench.common.tree.LittleTree.*;

import static gbench.common.matlib.MatlibCanvas.println;
import static gbench.common.tree.LittleTree.JOIN;
import static gbench.common.tree.LittleTree.TUPLES;
import static gbench.common.tree.LittleTree.compose_f;
import static gbench.common.tree.LittleTree.IRecord.*;
import static gbench.common.tree.LittleTree.SQL.nsql;
import static gbench.common.tree.LittleTree.Term.*;

/**
 * 
 * @author gbench
 *
 */
public class JunitSQL {

    @Test
    public void foo() {
        final var builder = IRecord.builder("#id,~32name,drcr,amount,createTime,description");
        final var rec = builder.get(1l, "name", 0, 2000d, LocalDateTime.now(), "-");// 生成一个数据示意图
        final var tableName = "entry";// 默认表名
        final var namedsql = new SQL(tableName, rec);
        System.out.println("create table:");
        int i=0;
        for(String sql:namedsql.createTable()) System.out.println((i++)+"\n"+sql);
        System.out.println(namedsql.insert());
        System.out.println(namedsql.update(REC("name","345")));
        // 需要注意，这里 使用 REC2 来存取空值
        System.out.println(namedsql.update(SimpleRecord.REC2("32name","345","drcr",null)));

    }
    
    @Test
    public void bar() {
        final var builder = IRecord.builder("#id,~32name,drcr,amount,createTime,description");
        final var rec = builder.get(1l, "name", 0, 2000d, LocalDateTime.now(), "-");// 生成一个数据示意图
        final var tableName = "entry";// 默认表名
        final var namedsql = new SQL(tableName, rec);
        System.out.println("create table:");
        int i=0;
        for(String sql:namedsql.createTable(true)) // 在事务中插入数据的时候，如果 对于自增长类型的字段 如果，指定了键值 会 出“主键重复”的错误的。
            System.out.println((i++)+"\n"+sql);
    }
    
    @Test
    public void qux() {
        final var builder = SQL.builder("order");
        final var order = REC("#id",1,"~userid",1,"~productid",1,"amount",1.0,"quantity",1.0,"createtime",LocalDateTime.now());
        final var torder = builder.get(order);
        torder.createTable(true).forEach(System.out::println);
        final var p = IRecord.builder(torder);
        System.out.println(p.get(order.toObjArray()));
        System.out.println(torder.insert());
        final var s = builder.get(order,order,order);
        System.out.println(s.insert());
    }
    
    @Test
    public void qux2() {
        // 写入数据库
        final var proto = REC("#id",1,"rankid",1,"24nation","中国","16continent","亚洲",
            "64gdp","121,128,073","gdpvalue",121128073,"32percent","8.8E-5","year",2019,"createtime",LocalDateTime.now());// 原型结构
        final var tblname = "t_gdp";
        final var sb = SQL.builder(tblname); // 狗仔entry sql 系列构建器具
        final var createsqls = sb.get(proto).createTable(true); // 生成createsqls
        final var eg = proto.aoks2rec(compose_f(e->e.str("name"),SQL::parseFieldName)).filter2("id");// 演示示例
        final var keys = eg.keys(); // 提取键名列表 // 键名
        final var s1 = JOIN( keys, "," ); // 设置键名
        final var s2 = JOIN( keys.stream().map(e -> "e." + e), "," ); // 键名
        final var entries = Stream.iterate(0, i->i+1).limit(10)
            .map(i->eg.filter2("#id").derive("rankid",i))
            .collect(Collectors.toList());
        
        TUPLES(createsqls).filter(t->t._1()!=1).map(t->t._2().replaceAll("-- .*\n", "")).forEach(System.out::println);
        Stream.of( nsql ( FT("insert delayed into tblname$ (s1$) values ${ foreach e in entries (s2$) }",REC("tblname$",tblname,"s1$",s1,"s2$",s2)), 
            REC( "entries", entries  )) ).map(SQL::string2).forEach( System.out::println );
        
        final var sql = FT("insert into tblname$ (name,sex) values (#name,#sex)",REC("tblname$","user","#name","张三","#sex","男")) ;
        System.out.println(sql);
    }
    
    @Test
    public void qux3() {
        final var sql = nsql("select * from t_user where id in ( ${ foreach a in entries a } )",REC("entries",L(1,2,3,4,5)));
        System.out.println(sql.string2());
        final var sql1 = nsql("select * from t_user where id in ( ${ foreach a in entries a } )",REC("entries","123456".split("")));
        System.out.println(sql1.string2());
    }
    
    @Test
    public void qux4() {
        final var line = "insert into ##tbl(id,name) values (##id,#name) ##comment";
        println("terms", SQL.getAllTerms(line));
        final var sql = nsql(line, REC("tbl", "t_user", "id", 1, "name", "zhangsan", "comment", "-- 插入语一条用户数据"));
        println(sql.string2());

        final var sql2 = nsql("insert into ##_0(id,name,rank) values (##_1,#_2,0)", "t_user", 1, "zhangsan");
        println(sql2.string2());
    }
    
    @Test
    public void qux5() {
        println(SQL.of("user",REC("name","zhangsan","sex","lisi"),REC("address","shanghai")).select("name,sex,address","and","or"));
        println(SQL.of("user").select("name,sex,address",null,null));
        println(SQL.of("user").select());
    }

}
